package game;

import java.util.ArrayList;
import java.util.List;

public class Room {
   
   public enum Direction {NORTH, EAST, SOUTH, WEST;}
   
   private String name;
   private Room north;
   private Room east;
   private Room west;
   private Room south;
   private boolean isExit = false;
   private List<Player> players;

   public Room(String name) {
      this.name = name;
      players = new ArrayList<Player>();
   }
   
   /**
    * Returns the list of directions to the selected room.
    * @param name	Sought room
    */
   public List<Direction> findPathTo(String name) {
      return findPath(name, null, new ArrayList<Room>());
   }
   
   /**
    * Recoursive method for making the returnlist of findPathTo(String name).
    */
   private ArrayList<Direction> findPath(String name, Direction lastDir, ArrayList<Room> visitedRoomList) {
      ArrayList<Direction> path = new ArrayList<Direction>();
      if (visitedRoomList.contains(this)) {
         return null;
      }
      visitedRoomList.add(this);
      if (this.name.equals(name)) {
         if (lastDir != null) path.add(lastDir);
         return path;
      }
      Room tempRoom;
      for (Direction d : Direction.values()) {
         tempRoom = get(d);
         if (tempRoom == null) {
            continue;
         }
         path = tempRoom.findPath(name, d, visitedRoomList);
         if (path != null && !path.isEmpty()) {
            if (lastDir != null) {
               path.add(0, lastDir);
            }
            return path;
         }
      }
      return null;
   }
   
   /**
    * Adds the player to the room.
    */
   public void addPlayer(Player p) {
      players.add(p);
   }
   /**
    * Removes the player form the room.
    */
   public void removePlayer(Player p) {
      players.remove(p);
   }
   
   
   /**
    * Returns if this path leads to a room.
    */
   public boolean validatePath(List<Character> dirs) {
      Room room = this;
      for (char c : dirs) {
         try {
            room = room.get(c);
         } catch (Exception e) {
            return false;
         }
      }
      if (room != null) return true;
      return false;
   }
   
   /**
    * Returns the room that was found after following the direction list.
    */
   public Room get(List<Character> dirs) {
      Room room = this;
      for (char c : dirs) {
         try {
            room = room.get(c);
         } catch (Exception e) {
            return null;
         }
      }
      if (room != null) return room;
      return null;
   }
   
   /**
    * Returns the room in direction d.
    */
   public Room get(Direction d) {
      if (d == Direction.NORTH) {
         return getNorth();
      } else if (d == Direction.EAST) {
         return getEast();
      } else if (d == Direction.SOUTH) {
         return getSouth();
      } else if (d == Direction.WEST) {
         return getWest();
      }
      return null;
   }
   
   /**
    * Returns the room in direction d.
    */
   public Room get(char d) {
      if (d == 'N') {
         return getNorth();
      } else if (d == 'E') {
         return getEast();
      } else if (d == 'S') {
         return getSouth();
      } else if (d == 'W') {
         return getWest();
      }
      return null;
   }
   //-------------
   public Room createNorth(String name) {
      if (north != null) {
         return north;
      }
      setNorth(new Room(name));
      return north;
   }
   
   public Room createEast(String name) {
      if (east != null) {
         return east;
      }
      setEast(new Room(name));
      return east;
   }
   
   public Room createSouth(String name) {
      if (south != null) {
         return south;
      }
      setSouth(new Room(name));
      return south;
   }
   
   public Room createWest(String name) {
      if (west != null) {
         return west;
      }
      setWest(new Room(name));
      return west;
   }
   //----------
   public Room getNorth() {
      return north;
   }

   public void setNorth(Room north) {
      this.north = north;
      if (north.getSouth() == null) {
         north.setSouth(this);
      }
   }

   public Room getEast() {
      return east;
   }

   public void setEast(Room east) {
      this.east = east;
      if (east.getWest() == null) {
         east.setWest(this);
      }
   }

   public Room getWest() {
      return west;
   }

   public void setWest(Room west) {
      this.west = west;
      if (west.getEast() == null) {
         west.setEast(this);
      }
   }

   public Room getSouth() {
      return south;
   }

   public void setSouth(Room south) {
      this.south = south;
      if (south.getNorth() == null) {
         south.setNorth(this);
      }
   }

   public boolean isExit() {
      return isExit;
   }

   public void setExit(boolean isExit) {
      this.isExit = isExit;
   }
   
   public List<Player> getPlayers() {
      return players;
   }

   @Override
   public String toString() {
      return "Room [name=" + name + ", ID=" + super.toString() + "]";
   }
   
   
}
